/**
 * 文件业务逻辑模块
 * 提供文件相关的业务处理功能
 */
// 使用统一配置入口模式导入helpers
const ProjectHelpers = require('../../config/project_helpers_config');
const pageHelper = ProjectHelpers.pageHelper;
const cloudHelper = ProjectHelpers.cloudHelper;
const fileHelper = ProjectHelpers.fileHelper;

class FileBiz {
	/**
	 * 获取文件扩展名
	 * @param {string} fileName 文件名
	 * @returns {string} 扩展名
	 */
	static getFileExt(fileName) {
		if (!fileName) return '';
		
		const lastDot = fileName.lastIndexOf('.');
		if (lastDot === -1) return '';
		
		return fileName.substring(lastDot + 1).toLowerCase();
	}

	/**
	 * 获取文件图标
	 * @param {string} fileName 文件名
	 * @returns {string} 图标路径
	 */
	static getFileIcon(fileName) {
		const ext = this.getFileExt(fileName);
		
		// 图片文件
		if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(ext)) {
			return '/images/file/image.png';
		}
		
		// 文档文件
		if (['doc', 'docx'].includes(ext)) {
			return '/images/file/word.png';
		}
		
		if (['xls', 'xlsx'].includes(ext)) {
			return '/images/file/excel.png';
		}
		
		if (['ppt', 'pptx'].includes(ext)) {
			return '/images/file/ppt.png';
		}
		
		if (ext === 'pdf') {
			return '/images/file/pdf.png';
		}
		
		if (['txt', 'log', 'md'].includes(ext)) {
			return '/images/file/text.png';
		}
		
		if (['zip', 'rar', '7z', 'tar', 'gz'].includes(ext)) {
			return '/images/file/zip.png';
		}
		
		// 其他类型
		return '/images/file/unknown.png';
	}

	/**
	 * 检查文件大小是否超过限制
	 * @param {Number} fileSize 文件大小（字节）
	 * @param {Number} maxSize 最大限制（MB）
	 * @returns {Boolean} 是否超过限制
	 */
	static checkFileSize(fileSize, maxSize = 10) {
		if (!fileSize) return false;
		
		// 转换MB为字节
		const maxBytes = maxSize * 1024 * 1024;
		
		return fileSize > maxBytes;
	}

	/**
	 * 格式化文件大小显示
	 * @param {number} size 文件大小(字节)
	 * @returns {string} 格式化后的大小
	 */
	static formatFileSize(size) {
		if (!size) return '0 B';
		
		const units = ['B', 'KB', 'MB', 'GB', 'TB'];
		let index = 0;
		let fileSize = size;
		
		while (fileSize >= 1024 && index < units.length - 1) {
			fileSize /= 1024;
			index++;
		}
		
		return fileSize.toFixed(2) + ' ' + units[index];
	}

	/**
	 * 判断是否为图片
	 * @param {String} fileName 文件名
	 * @returns {Boolean} 是否为图片
	 */
	static isImageFile(fileName) {
		const ext = this.getFileExt(fileName);
		return ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(ext);
	}

	/**
	 * 判断是否为文档
	 * @param {String} fileName 文件名
	 * @returns {Boolean} 是否为文档
	 */
	static isDocFile(fileName) {
		return ['doc', 'docx'].includes(this.getFileExt(fileName));
	}

	/**
	 * 获取文件类型
	 * @param {String} fileName 文件名
	 * @returns {String} 文件类型
	 */
	static getFileType(fileName) {
		return this.getFileExt(fileName);
	}

	/**
	 * 打开文件
	 * @param {Object} file 文件对象
	 * @returns {Promise} 文件打开结果
	 */
	static async openFile(file) {
		try {
			if (!file || !file.fileID) {
				throw new Error('文件信息不完整');
			}
			
			// 获取文件临时访问URL
			let url = '';
			if (file.fileID) {
				const result = await cloudHelper.getTempFileURLOne(file.fileID);
				if (!result) throw new Error('获取文件链接失败');
				url = result;
			} else if (file.url) {
				url = file.url;
			}
			
			if (!url) throw new Error('文件链接为空');
			
			// 根据文件类型打开文件
			const isImage = this.isImageFile(file.name || '');
			
			if (isImage) {
				// 打开图片预览
				wx.previewImage({
					urls: [url],
					current: url
				});
			} else {
				// 打开文档预览
				await fileHelper.openDoc({
					path: url,
					name: file.name || '文件'
				});
			}
			
			return true;
		} catch (err) {
			console.error('打开文件失败', err);
			pageHelper.showModal('打开文件失败: ' + err.message);
			return false;
		}
	}

	/**
	 * 下载文件
	 * @param {Object} file 文件对象
	 * @returns {Promise} 下载结果
	 */
	static async downloadFile(file) {
		try {
			if (!file || !file.fileID) {
				throw new Error('文件信息不完整');
			}
			
			pageHelper.showLoading('文件下载中...');
			
			// 获取文件临时访问URL
			let url = '';
			if (file.fileID) {
				const result = await cloudHelper.getTempFileURLOne(file.fileID);
				if (!result) throw new Error('获取文件链接失败');
				url = result;
			} else if (file.url) {
				url = file.url;
			}
			
			if (!url) throw new Error('文件链接为空');
			
			// 下载文件
			const downloadResult = await new Promise((resolve, reject) => {
				const downloadTask = wx.downloadFile({
					url: url,
					success: res => {
						if (res.statusCode === 200) {
							resolve(res.tempFilePath);
						} else {
							reject(new Error(`下载失败，状态码: ${res.statusCode}`));
						}
					},
					fail: err => {
						reject(new Error('下载失败: ' + err.errMsg));
					}
				});
				
				// 监听下载进度
				downloadTask.onProgressUpdate(res => {
					const progress = res.progress;
					pageHelper.showLoading(`下载中 ${progress}%`);
				});
			});
			
			pageHelper.hideLoading();
			
			// 保存文件到本地
			if (this.isImageFile(file.name || '')) {
				await new Promise((resolve, reject) => {
					wx.saveImageToPhotosAlbum({
						filePath: downloadResult,
						success: () => {
							resolve();
						},
						fail: err => {
							reject(new Error('保存图片失败: ' + err.errMsg));
						}
					});
				});
				
				pageHelper.showSuccToast('图片已保存到相册');
			} else {
				// 打开文件
				wx.openDocument({
					filePath: downloadResult,
					showMenu: true,
					success: () => {
						pageHelper.showSuccToast('文件打开成功');
					},
					fail: err => {
						pageHelper.showModal('打开文件失败: ' + err.errMsg);
					}
				});
			}
			
			return true;
		} catch (err) {
			console.error('下载文件失败', err);
			pageHelper.hideLoading();
			pageHelper.showModal('下载文件失败: ' + err.message);
			return false;
		}
	}

	/**
	 * 上传文件
	 * @param {Object} options 上传选项
	 * @param {String} options.projectId 项目ID
	 * @param {String} options.tag 文件标签
	 * @param {String} options.desc 文件描述
	 * @param {Function} options.success 成功回调
	 * @param {Function} options.fail 失败回调
	 */
	static chooseUploadFile(options = {}) {
		try {
			// 文件选择配置
			const chooseFileConfig = {
				count: 1,
				type: 'file',
				extension: ['.jpg', '.jpeg', '.png', '.gif', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.txt', '.zip', '.rar'],
				success: async function(res) {
					if (res.tempFiles.length === 0) {
						return;
					}

					const tempFile = res.tempFiles[0];
					const fileName = tempFile.name || dataHelper.genRandomString(10) + '.unknown';
					const fileSize = tempFile.size;
					const filePath = tempFile.path;
					const fileType = FileBiz.getFileType(fileName);

					// 文件大小限制：50MB
					const MAX_SIZE = 50 * 1024 * 1024;
					if (fileSize > MAX_SIZE) {
						pageHelper.showModal('文件大小不能超过50MB');
						if (options.fail) options.fail('文件大小超限');
						return;
					}

					wx.showLoading({ title: '文件上传中...' });

					try {
						// 上传文件到云存储
						const cloudResult = await cloudHelper.uploadFile(filePath, fileName, 'plm_file');
						
						if (!cloudResult || !cloudResult.fileID) {
							wx.hideLoading();
							pageHelper.showModal('上传失败，请重试');
							if (options.fail) options.fail('上传文件失败');
							return;
						}

						// 保存文件信息到数据库
						const fileData = {
							projectId: options.projectId || '',
							name: fileName,
							type: fileType,
							tag: options.tag || '',
							desc: options.desc || '',
							fileID: cloudResult.fileID,
							size: fileSize
						};

						// 调用服务保存文件信息
						const result = await FileService.uploadFile(fileData);
						
						wx.hideLoading();
						
						if (!result) {
							pageHelper.showModal('文件信息保存失败');
							if (options.fail) options.fail('文件信息保存失败');
							return;
						}
						
						if (options.success) options.success(result);
						
					} catch (err) {
						wx.hideLoading();
						console.error('文件上传失败', err);
						pageHelper.showModal('文件上传失败: ' + err.message);
						if (options.fail) options.fail(err.message);
					}
				},
				fail: function(err) {
					console.error('选择文件失败', err);
					if (options.fail) options.fail(err.errMsg);
				}
			};

			// 选择文件
			wx.chooseMessageFile(chooseFileConfig);
			
		} catch (err) {
			console.error('选择文件操作失败', err);
			pageHelper.showModal('选择文件操作失败: ' + err.message);
			if (options.fail) options.fail(err.message);
		}
	}

	/**
	 * 上传图片
	 * @param {Object} options 上传选项
	 * @param {String} options.projectId 项目ID
	 * @param {String} options.tag 文件标签
	 * @param {String} options.desc 文件描述
	 * @param {Function} options.success 成功回调
	 * @param {Function} options.fail 失败回调
	 */
	static chooseUploadImage(options = {}) {
		try {
			// 图片选择配置
			const chooseImageConfig = {
				count: 1,
				sizeType: ['compressed'],
				sourceType: ['album', 'camera'],
				success: async function(res) {
					if (res.tempFilePaths.length === 0) {
						return;
					}

					const filePath = res.tempFilePaths[0];
					// 生成文件名
					const fileName = dataHelper.genRandomString(10) + '.jpg';
					
					wx.showLoading({ title: '图片上传中...' });

					try {
						// 获取图片信息
						const imageInfo = await new Promise((resolve, reject) => {
							wx.getImageInfo({
								src: filePath,
								success: resolve,
								fail: reject
							});
						});
						
						// 上传图片到云存储
						const cloudResult = await cloudHelper.uploadFile(filePath, fileName, 'plm_file');
						
						if (!cloudResult || !cloudResult.fileID) {
							wx.hideLoading();
							pageHelper.showModal('上传失败，请重试');
							if (options.fail) options.fail('上传图片失败');
							return;
						}

						// 图片文件大小，没有时使用预估值
						const fileSize = imageInfo.size || (imageInfo.width * imageInfo.height / 3);

						// 保存文件信息到数据库
						const fileData = {
							projectId: options.projectId || '',
							name: fileName,
							type: 'image',
							tag: options.tag || '',
							desc: options.desc || '',
							fileID: cloudResult.fileID,
							size: fileSize
						};

						// 调用服务保存文件信息
						const result = await FileService.uploadFile(fileData);
						
						wx.hideLoading();
						
						if (!result) {
							pageHelper.showModal('图片信息保存失败');
							if (options.fail) options.fail('图片信息保存失败');
							return;
						}
						
						if (options.success) options.success(result);
						
					} catch (err) {
						wx.hideLoading();
						console.error('图片上传失败', err);
						pageHelper.showModal('图片上传失败: ' + err.message);
						if (options.fail) options.fail(err.message);
					}
				},
				fail: function(err) {
					console.error('选择图片失败', err);
					if (options.fail) options.fail(err.errMsg);
				}
			};

			// 选择图片
			wx.chooseImage(chooseImageConfig);
			
		} catch (err) {
			console.error('选择图片操作失败', err);
			pageHelper.showModal('选择图片操作失败: ' + err.message);
			if (options.fail) options.fail(err.message);
		}
	}

	/**
	 * 获取文件列表
	 * @param {Object} params 查询参数
	 * @returns {Promise} 文件列表
	 */
	static async getFileList(params) {
		return await FileService.getFileList(params);
	}

	/**
	 * 获取文件详情
	 * @param {String} id 文件ID
	 * @returns {Promise} 文件详情
	 */
	static async getFileDetail(id) {
		return await FileService.getFileDetail(id);
	}

	/**
	 * 删除文件
	 * @param {String} id 文件ID
	 * @returns {Promise} 删除结果
	 */
	static async deleteFile(id) {
		return await FileService.deleteFile(id);
	}

	/**
	 * 更新文件信息
	 * @param {Object} data 文件数据
	 * @returns {Promise} 更新结果
	 */
	static async updateFile(data) {
		return await FileService.updateFile(data);
	}
}

module.exports = FileBiz; 